#pragma once
#include<iostream>
#include<math.h>

using namespace std;

const double pai = 3.1415926; 
const double e = 2.71828;
const int MAX = 1000;  //迭代次数上界
const double delta = 0.01;     //所需区间误差
const double epsilon = 0.001;   //所需函数值误差

double function(double x)   //需要求零点的函数(需修改程序提供)
{
		return  x*x*x - 12*x*x + 3*x + 1;
}

double derivative(double x)   //需要求零点的函数的导函数(需修改程序提供)
{
	return 1 - (1 / cos(x)) * (1 / cos(x));
}

int sgn(double x)
{
	if (x > 0)
		return 1;
	else if (x < 0)
		return -1;
	else
		return 0;
}

class EquationSolver
{
public:
	virtual void solve() = 0;
};

class bisection : public EquationSolver
{
private:
	double a, h, c, w, u;
public:	
	bisection(double a, double b)
	{
		this->h = b - a;
		this->a = a;
		this->u = function(a);
	}
	void solve()
	{
		int count = 0;  //迭代次数
		for (int i = 0; i <= MAX; i++)
		{
			count++;
			this->h /= 2;
			this->c = this->a + this->h;
			if (abs(this->h) < delta || i == MAX)
				break;

			this->w = function(this->c);
			if (abs(this->w) < epsilon)
				break;
			else if (sgn(this->w) == sgn(this->u))
				this->a = this->c;
			if (count >= MAX){
				cout << "迭代失败" << endl;
				break;
				}
				
		}
		
		
			cout << "零点为：" << this->c << endl;
			cout << "迭代次数为：" << count << endl;
		
	}	
};

class Newton : public EquationSolver
{
private:
	double x, u;
public:
	Newton(double x0)
	{
		this->x = x0;
	}
	Newton(double a,double b)   
	{
		this->x = (a + b) / 2;
	}
	void solve()
	{
		int count = 0;
		for (int i = 0; i <= MAX; i++)
		{
			count++;
			this->u = function(x);
			if (abs(u) < epsilon)
				break;
			this->x -= this->u /derivative(this->x);
			if (count >= MAX){
				cout << "迭代失败" << endl;
				break;
			}
			
		}
		
		
		{
			cout << "零点为：" << this->x << endl;
			cout << "迭代次数为：" << count << endl;
		}
	}
};

class secant : public EquationSolver
{
private:
	double x_1, x_0, u, v, s;
public:
	secant(double x1,double x0)
	{
		if (x1 < x0)
		{
			double temp = x0;   //若先输入的数小，则进行交换
			x0 = x1;
			x1 = temp;
		}
		this->x_1 = x1;
		this->x_0 = x0;
		u = function(x_1);
		v = function(x_0);
	}
	void solve()
	{
		int count = 0;
		for (int i = 0; i <= MAX; i++)
		{
			count++;
			this->s = (this->x_1 - this->x_0) / (u - v);
			this->x_0 = this->x_1;
			this->v = this->u;
			this->x_1 -= this->u * this->s;
			if (abs(this->x_1 - this->x_0) < delta)
				break;

			this->u = function(this->x_1);
			if (abs(this->u) < epsilon)
				break;
			if (count >= MAX){
				cout << "迭代失败" << endl;
				break;
			}
			
		}
		
		
		
			cout << "零点为：" << this->x_1 << endl;
			cout << "迭代次数为：" << count << endl;
		
	}
};